/**
 * @brief Maximum number of routing table entries supported per network device
 * This constant defines the upper limit for routing entries that can be
 * stored and managed for each individual network interface device to
 * prevent memory overflow and ensure system stability
 */
#define MAX_ROUTES 128

/**
 * @brief Maximum number of network devices supported in routing table
 * This constant defines the upper limit for distinct network interface
 * devices that can be tracked and managed within the routing table
 * structure, including both physical and virtual interfaces
 */
#define MAX_DEVICES 16

/**
 * @brief Maximum character length for string fields in routing structures
 * This constant defines the buffer size allocated for string-based fields
 * including device names, IP addresses, and subnet masks to prevent
 * buffer overflow vulnerabilities and ensure data integrity
 */
#define MAX_STR_LEN 64

/**
 * @brief Individual route entry structure for destination network definition
 * This structure represents a single routing table entry containing the
 * destination network address and corresponding subnet mask for packet
 * forwarding decisions in the network stack
 */
typedef struct {
    /**
     * @brief Destination network address in dotted-decimal notation
     * Stores the target network address for route matching (e.g., "192.168.1.0")
     * Used by the kernel to determine if outgoing packets match this route
     */
    char destination[MAX_STR_LEN];
    
    /**
     * @brief Subnet mask for destination network in dotted-decimal notation
     * Defines the network portion of the destination address (e.g., "255.255.255.0")
     * Used in conjunction with destination to determine the network scope
     */
    char mask[MAX_STR_LEN];
} Route;

/**
 * @brief Network device structure with associated routing entries
 * This structure represents a complete network interface with all its
 * configured routing table entries, providing device-specific routing
 * configuration management capabilities
 */
typedef struct {
    /**
     * @brief Network interface device name identifier
     * Stores the name of the network device (e.g., "eth0", "ppp0", "wlan0")
     * Used to associate routing entries with specific physical or virtual interfaces
     */
    char device[MAX_STR_LEN];
    
    /**
     * @brief Array of routing table entries for this network device
     * Contains all the configured routes associated with this specific
     * network interface, up to the MAX_ROUTES limit
     */
    Route routes[MAX_ROUTES];
    
    /**
     * @brief Current count of active routing entries for this device
     * Tracks the number of valid routes stored in the routes array to
     * prevent accessing uninitialized or invalid array elements
     */
    int route_count;
} Device;

/**
 * @brief Complete routing table structure for system-wide route management
 * This master structure contains all network devices and their associated
 * routing entries, plus the system default route configuration for
 * comprehensive routing table management and synchronization
 */
typedef struct {
    /**
     * @brief Array of network devices with their routing configurations
     * Stores all tracked network interfaces and their associated routing
     * tables, up to the MAX_DEVICES system limit
     */
    Device devices[MAX_DEVICES];
    
    /**
     * @brief Current count of active network devices in the table
     * Tracks the number of valid devices stored in the devices array to
     * ensure proper array bounds checking during operations
     */
    int device_count;
    
    /**
     * @brief Default gateway device for system-wide default routing
     * Specifies which network device serves as the default route for
     * packets that don't match any specific destination in the routing table
     */
    char default_device[MAX_STR_LEN];
} RouteTable;

/**
 * @brief Execute system command and capture output as dynamically allocated string
 * This function provides a safe wrapper around popen/pclose system calls to
 * execute shell commands and retrieve their standard output for processing
 * @param command: Null-terminated string containing the shell command to execute
 *                 The command should be a valid shell command that can be
 *                 executed in the system environment
 * @return char*: Returns a dynamically allocated string containing the command
 *                output, or NULL if command execution failed or memory
 *                allocation error occurred. The caller is responsible for
 *                freeing the returned string to prevent memory leaks.
 */
char *execc(const char *command) ;

/**
 * @brief Parse complete routing table output and populate RouteTable structure
 * This function processes multi-line output from system routing commands
 * (e.g., 'ip route' or 'route -n') and extracts all routing information
 * into the provided RouteTable structure for further processing
 * @param table: Pointer to RouteTable structure to be populated with parsed
 *               routing data. The structure should be initialized before
 *               calling this function to ensure proper memory management.
 * @param output: Multi-line string containing the raw output from system
 *                routing commands. Each line should represent a single
 *                routing table entry in the system's standard format.
 */
void parse_routes(RouteTable *table, const char *output);

/**
 * @brief Display complete routing table contents in human-readable format
 * This debug and diagnostic function prints the entire routing table
 * structure to standard output, showing all devices, their routes, and
 * the default gateway configuration for verification purposes
 * @param table: Pointer to RouteTable structure containing the routing
 *               data to be displayed. The structure should be properly
 *               populated with valid routing information before calling.
 */
void print_routes(const RouteTable *table);

/**
 * @brief Parse IP address and subnet mask from CIDR notation input string
 * This utility function processes network address input in CIDR format
 * (e.g., "192.168.1.0/24") and separates it into individual IP address
 * and subnet mask components for routing table operations
 * @param input: Input string containing IP address in CIDR notation format
 *               or standard dotted-decimal format. If CIDR notation is
 *               used, the mask will be calculated from the prefix length.
 * @param ip: Output buffer to store extracted IP address component. The
 *            buffer must be at least MAX_STR_LEN bytes to ensure safe
 *            string operations and prevent buffer overflow.
 * @param mask: Output buffer to store calculated or extracted subnet mask.
 *              The buffer must be at least MAX_STR_LEN bytes. If the input
 *              doesn't contain CIDR notation, a default mask may be applied.
 */
void parse_ip_and_mask(const char *input, char *ip, char *mask) ;

/**
 * @brief Parse single line from routing command output and extract route information
 * This function processes individual lines from system routing table output,
 * extracting destination networks, subnet masks, and associated network
 * interfaces for addition to the routing table structure
 * @param rt: Pointer to RouteTable structure to be updated with the parsed
 *            route information. The structure will be modified in-place
 *            with the new route entry if parsing is successful.
 * @param line: Single line string from routing command output to be parsed.
 *              The line should follow the standard format of system routing
 *              table output for proper extraction of routing parameters.
 */
void parse_route_line(RouteTable *rt, const char *line) ;

/**
 * @brief Save complete routing table structure to persistent configuration file
 * This function serializes the entire routing table structure and writes it
 * to a persistent storage file (typically JSON format) for system configuration
 * preservation across reboots and application restarts
 * @param table: Pointer to RouteTable structure containing the routing data
 *               to be saved to persistent storage. The structure should
 *               contain valid, complete routing information.
 * @return int: Returns TRUE (non-zero) if the routing table was successfully
 *              saved to the configuration file, FALSE (zero) if any error
 *              occurred during the file writing or serialization process.
 */
int save_route_table_to_file(RouteTable *table) ;

/**
 * @brief Synchronize system routing table with application routing structure
 * This main synchronization function executes system routing commands to
 * retrieve the current routing table, parses the output, and updates the
 * application's RouteTable structure with the current system state
 * @param table: Pointer to RouteTable structure to be synchronized with
 *               the current system routing table. The structure will be
 *               populated with the latest routing information from the
 *               operating system.
 * @return int: Returns TRUE if synchronization completed successfully and
 *              the RouteTable structure was updated with current system
 *              routing data, FALSE if any step in the synchronization
 *              process failed (command execution, parsing, or saving).
 */
int wwan_route_sync(RouteTable * table);

/**
 * @brief Add route entry to specific network device in routing table structure
 * This function manages the routing table by adding new route entries to
 * existing devices or creating new device entries when necessary, with
 * comprehensive error checking and capacity validation
 * @param rt: Pointer to RouteTable structure to be updated with the new
 *            route entry. The structure will be modified in-place to
 *            include the new routing configuration.
 * @param device: Network interface device name to which the route should
 *                be added (e.g., "ppp0", "eth1"). If the device doesn't
 *                exist in the table, a new device entry will be created.
 * @param destination: Destination network address for the new route entry
 *                     in dotted-decimal notation (e.g., "192.168.1.0").
 *                     This specifies the target network for packet routing.
 * @param mask: Subnet mask associated with the destination network in
 *              dotted-decimal notation (e.g., "255.255.255.0"). This
 *              defines the scope of the destination network.
 */
void add_route_to_device(RouteTable *rt, const char *device, const char *destination, const char *mask) ;